package com.fslq.pipeline;

import com.fslq.pojo.EnrollmentPlan;
import com.fslq.service.SchoolService;

import org.openqa.selenium.*;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import static java.lang.Thread.sleep;

/*招生计划*/
@Component
public class EnrollmentPlanDataPipeline implements Pipeline {
    @Autowired
    private SchoolService schoolService;
    @Override
    public void process(ResultItems resultItems, Task task) {

       // String path="D:\\WorkSpace\\Idea\\crawler\\crawler_college\\src\\main\\resources\\startparam.txt";
       // String path=this.getClass().getClassLoader().getResource("./startparam.txt").getPath() ;
       // System.setProperty( "webdriver.chrome.driver","C:\\Users\\22966\\AppData\\Local\\Google\\Chrome\\Application\\chromedriver.exe" );
        WebDriver driver=new ChromeDriver( /*new ChromeOptions().addArguments( "--headless" )*/ );
        try{
            List<Long> allSchoolId=schoolService.IsExistAllId();
            System.out.println("遍历ID："+allSchoolId);
            AtomicInteger i=new AtomicInteger(1);
            do {
                allSchoolId.stream().forEach( p->{
                    //loop crawler the exception school
              /*  String s=null;
                try( BufferedReader br=new BufferedReader( new InputStreamReader(new FileInputStream(new File(path)),StandardCharsets.UTF_8 ) )
                ){
                    s=br.readLine();
                }catch(IOException e){
                    e.printStackTrace();
                }
                int startParam= Integer.parseInt( s.trim());*/
                    System.out.println("第"+i.get()+"个学校编号："+p );
                    try {
                            sleep( 10*i.get() );
                            Set<EnrollmentPlan> enrollmentPlan=findEnrollmentPlan( driver,p );
                            sleep( 15*i.get() );
                            System.out.println("*********************************************");
                        int count=0;
                      /*  for (EnrollmentPlan plan : enrollmentPlan) {
                            if (plan.getPlanNum()==0) {
                                count++;
                            }
                        }*/
                            //System.out.println(enrollmentPlan);
                            System.out.println("*********************************************");
                            if (count==0)
                            {
                                sleep( 20*i.get() );
                                schoolService.saveAllEnrollmentPlan(enrollmentPlan);
                                sleep( 25*i.get() );
                            }
                    } catch (Exception e) {
                  /*  try(BufferedWriter  bw=new BufferedWriter( new OutputStreamWriter(new FileOutputStream(new File(path)),StandardCharsets.UTF_8 ))){

                        bw.write(String.valueOf(  i.get()) );
                        i.set( i.get()-1 );
                        bw.flush();
                    }catch(IOException ex){
                        ex.printStackTrace();
                    }*/
                        System.out.println("第"+i.get()+"个学校编号："+p+"歇菜:"+e.getMessage() );
                    }
                    i.getAndIncrement();
                } );
                allSchoolId=schoolService.IsExistAllId();
            }while (allSchoolId.size()==0);


        }catch(Exception e){
            System.out.println( "异常："+e.getMessage() );
        } finally {
            //关闭浏览器（这个包括驱动完全退出，会清除内存），close 是只关闭浏览器
            driver.quit();
        }
    }

    private Set<EnrollmentPlan> findEnrollmentPlan(WebDriver driver, Long p) throws InterruptedException {
        int time=100;
        Set<EnrollmentPlan> lists=new  HashSet<>(  );
        //1.Get first page
        //https://gkcx.eol.cn/school/338/provinceline
        WebDriverWait wait=new WebDriverWait( driver,50 );
        /**
         * /html/body/div[4]/div/div[2]/div/div[2]/div[1]/div
         *请选择所在省份及城市
         * /html/body/div[4]/div/div[2]/div/div[2]/div[3]/button
         */
        JavascriptExecutor driver_js=((JavascriptExecutor) driver);
        AtomicReference<String> path=new AtomicReference<>( "/html/body/div[4]/div/div[2]/div/div[2]/div[3]/button" );
        driver.get("https://gkcx.eol.cn/school/" +p+"/provinceline");
        sleep( 3*time );
    //    if(isLocation(driver,path.get() ))
       //     wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path.get()))).click();
       // sleep( time );
        path.set( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[1]/div/div[3]/form/div/div/div/span/div/div/div/div" );
       /* if(wait.until( ExpectedConditions.elementToBeClickable( driver.findElement( By.xpath( path.get() ) ) ) ).isDisplayed()){
            wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath( path.get() ))).click();
        }*/
        WebElement until3 = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path.get())));
        driver_js.executeScript( "arguments[0].click();",until3 );
        // sleep(time*3);

        path.set( "/html/body/div[4]/div/div/div/ul/li" );
        //waitToBeLoaded( driver,path.get() );
        sleep(time);
        List<WebElement> until1=wait.until( ExpectedConditions.presenceOfAllElementsLocatedBy( By.xpath( path.get() ) ) );
       // driver_js.executeScript( "arguments[0].click();",until1 );

        if(until1.size()<2&&(until1.get( 0 ).getText().contains( "年份" )||!until1.get( 0 ).getText().contains( "2018" )))
        {
            EnrollmentPlan enrollmentPlan=new EnrollmentPlan();
            enrollmentPlan.setSchoolId( p );
            lists.add( enrollmentPlan );
//            System.out.println("运行");
            return lists;
        }else if(until1.size()==1&&until1.get( 0 ).getText().contains( "2018" )) {
//            System.out.println("运行1");
            wait.until( ExpectedConditions.presenceOfElementLocated(By.xpath( path.get() )  ) ).click();
        }else if(until1.size()>2){
//            System.out.println("运行2");
            WebElement until = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path.get() + "[2]")));
            driver_js.executeScript( "arguments[0].click();",until );
        }
        //3.Choose province
        path.set( "//*[@id='root']/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[1]/div/div[1]/div/div/div" );
    //    waitToBeLoaded( driver,path.get() );
        WebElement until7 = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path.get())));
        driver_js.executeScript( "arguments[0].click();",until7 );
        path.set( "/html/body/div[5]/div/div/div/ul/li" );
        //waitToBeLoaded( driver,path.get() );

        List<WebElement> provinces = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath( path.get() )));
        for (WebElement s : provinces) {
            List<EnrollmentPlan> list=new ArrayList<>();
            path.set( "//*[@id='root']/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[1]/div/div[1]/div/div/div" );
            waitToBeLoaded( driver,path.get() );
            WebElement until8 = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path.get())));
            driver_js.executeScript( "arguments[0].click();",until8 );
            try{
                sleep( time *3 );
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            Actions actions=new Actions( driver ).moveToElement( s );
            //二级菜单下拉框滚动
            actions.sendKeys( Keys.ARROW_DOWN );
            actions.click( s ).perform();
            try{
                sleep( time *2);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            String temp_pro=wait.until( ExpectedConditions.presenceOfElementLocated( By.xpath( path.get()+"/div" ) ) ).getAttribute( "title" );
            //4.Choose subject type
            path.set( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div/div/div" );
            waitToBeLoaded( driver,path.get() );
            WebElement until6 = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path.get())));
            driver_js.executeScript( "arguments[0].click();",until6 );
            path.set( "/html/body/div[6]/div/div/div/ul/li" );
            waitToBeLoaded( driver,path.get() );
            List<WebElement> sub_types=wait.until( ExpectedConditions.presenceOfAllElementsLocatedBy( By.xpath( path.get() ) ) );

            for (WebElement sub : sub_types) {
                if(sub.getText().equals( "科类" ))
                    continue;
                path.set( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div/div/div" );
                waitToBeLoaded( driver,path.get() );
                //4.Choose subject type
                WebElement until5 = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path.get())));
                driver_js.executeScript( "arguments[0].click();",until5 );
                new Actions( driver ).moveToElement( sub ).click().perform();
                //5.Choose betch
                path.set( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[1]/div/div[4]/form/div/div/div/span/div" );
                waitToBeLoaded( driver,path.get() );
                WebElement until=wait.until( ExpectedConditions.presenceOfElementLocated( By.xpath( path.get() ) ) );
                //处理异常：element click intercepted: Element <div class="ant-select-selection
                driver_js.executeScript( "arguments[0].click();",until );
                path.set( "/html/body/div[7]/div/div/div/ul/li" );
                waitToBeLoaded( driver,path.get() );
                try{
                    sleep( 2*time );
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
//                System.out.println("*******1");
                List<WebElement> betchs=wait.until( ExpectedConditions.presenceOfAllElementsLocatedBy( By.xpath( path.get() ) ) );
//                System.out.println("**********"+betchs.size());
                for (WebElement b : betchs) {
                    try{
                        sleep( time*2  );
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
//                    System.out.println("*********3");
                    new Actions( driver ).moveToElement( b ).click().perform();
//                    System.out.println("********4");
                    String temp_bet=driver.findElement( By.xpath( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[1]/div/div[4]/form/div/div/div/span/div/div" ) ).getText();
                    try{
                        sleep( time*2  );
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
//                    System.out.println("***********5");
                    if(temp_bet.equals( "批次" ))
                        continue;
                    //6.Get page's content
                    path.set( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[2]/div[1]/table/tbody/tr[2]" );
                    boolean isEmpty=IsEmptyTds(driver,path.get());
                    if(!isEmpty)
                    {
                        path.set( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[2]/div[3]/div/div/ul/li" );
                        List<WebElement> do_page=wait.until( ExpectedConditions.presenceOfAllElementsLocatedBy( By.xpath( path.get()) ) );
                        Integer last_page_num=do_page.size()-2;
                        //6.2 for..
                        do {

                            //6.3 get..<tr>
                            path.set( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[2]/div[1]/table/tbody/tr[position()>1]" );
                            //waitToBeLoaded( driver,path.get() );
                            try{
                                sleep( 20*time );
                            }catch(InterruptedException e){
                                e.printStackTrace();
                            }
                            List<WebElement> trs=wait.until( ExpectedConditions.presenceOfAllElementsLocatedBy( By.xpath( path.get() ) ) );
                            for (WebElement tr : trs) {//G
                                try{
                                    sleep( time );
                                }catch(InterruptedException e){
                                    e.printStackTrace();
                                }
                                // et <td>
                                System.out.println("44444444");
                                sleep(time*10);
                                List<WebElement> tds=tr.findElements( By.xpath( "td" ) );
                                String temp=tds.get( 0 ).getText();
                                if("-".equals( temp )){
//                                    System.out.println( "遇到‘-’跳出" );
                                    continue;
                                }
                                EnrollmentPlan enrollmentPlan=new EnrollmentPlan();
                                enrollmentPlan.setBatch( temp_bet );
                                enrollmentPlan.setSchoolId( p );
                                enrollmentPlan.setProvince( temp_pro );
                                enrollmentPlan.setSpecialName( temp );
                                enrollmentPlan.setSubjectType( tds.get( 1 ).getText() );
                                enrollmentPlan.setSpecialType( tds.get( 2 ).getText() );
                                String temp_num_1=tds.get( 3 ).getText();
                                String temp_num_2=tds.get( 4 ).getText();
                                if(!temp_num_1.equals( "-" )&&temp_num_2.equals( "-" ))
                                    enrollmentPlan.setPlanNum( Long.parseLong( temp_num_1 ) );
                                if(!temp_num_2.equals( "-" )&&temp_num_1.equals( "-" ))
                                    enrollmentPlan.setPlanNum( Long.parseLong( temp_num_2 ) );
                                sleep( time );
                                System.out.println(enrollmentPlan);
                                lists.add( enrollmentPlan );
                            }
                            //下一页
                            if(do_page.size() > 3){
                                int next=do_page.size()-1;
                                System.out.println("5555555555");
                                sleep(time*15);
                                //wait.until( ExpectedConditions.elementToBeClickable( do_page.get( next ) ) ).click();
                                WebElement until2 = do_page.get(next);
                                driver_js.executeScript("arguments[0].click();",until2);

                            }
                            last_page_num--;
                        } while (last_page_num > 0);
                    }

                    //批次跳转
                    path.set( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[1]/div/div[4]/form/div/div/div/span/div" );
                    waitToBeLoaded( driver,path.get() );
                    wait.until( ExpectedConditions.presenceOfElementLocated( By.xpath( path.get() ) ) ).click();
                }
                //批次初始化
                if(betchs.size() > 1){
                    try{
                        sleep( time  );
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                    path.set( "/html/body/div[1]/div/div/div/div/div/div/div[3]/div[1]/div[1]/div/div[2]/div[1]/div/div[4]/form/div/div/div/span/div/div" );
                    waitToBeLoaded( driver,path.get() );
                    WebElement until4 = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path.get())));
                    driver_js.executeScript( "arguments[0].click();",until4 );
                    try{
                        sleep( time );
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                    path.set( "/html/body/div[7]/div/div/div/ul/li[1]" );
                    waitToBeLoaded( driver,path.get() );
//                    System.out.println( "遇到‘-’跳出1" );
                    WebElement until2=wait.until( ExpectedConditions.presenceOfElementLocated( By.xpath( path.get() ) ) );
//                    System.out.println( "遇到‘-’跳出2" );
                    try{
                        sleep( time );
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
//                    System.out.println( "遇到‘-’跳出3" );
                    new Actions( driver ).moveToElement( until2 ).click().perform();
//                    System.out.println( "遇到‘-’跳出4" );
                    try{
                        sleep( time );
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
                //鼠标悬浮事件点击
                try{
                    sleep( time );
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            //schoolService.saveAllEnrollmentPlan( lists );
        }
        //7 Save lists
        return lists;
    }

    private boolean IsEmptyTds(WebDriver driver,String s) throws InterruptedException {
        WebDriverWait wait=new WebDriverWait( driver,20 );
        WebElement tr=wait.until( ExpectedConditions.presenceOfElementLocated( By.xpath( s ) ) );
        String td=tr.findElements( By.xpath( "td" ) ).get( 0 ).getText();
        return td.equals( "-" );
    }

    //阻塞
    private void waitToBeLoaded(WebDriver driver,String path) {
        while (!isLocation( driver,path )) {
            try{
                //System.out.println(1);
                sleep( 500 );
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        try{
            sleep( 500 );
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
    //判断
    private boolean isLocation(WebDriver driver,String path) {
        try{
            sleep( 500 );
            driver.findElement( By.xpath( path ) );
            System.out.println("定位到:"+path);
            return true;
        }catch(Exception e){
            System.out.println("定位不到:"+path);
            return false;
        }
    }
    /**
     * public static Func<IWebDriver, bool> ElementIsVisibleAndEnabled(IWebElement element)
     * {
     *     return (driver) =>
     *     {
     *         try
     *         {
     *             return element.Displayed && element.Enabled;
     *         }
     *         catch (Exception)
     *         {
     *             // If element is null, stale or if it cannot be located
     *             return false;
     *         }
     *     };
     * }
     */
}
